package com.qdlc.p2p.biz.service;

import java.text.MessageFormat;
import java.util.List;

import javax.annotation.Resource;

import com.qd.p2p.sina.pay.enums.AccountType;
import com.qd.p2p.sina.pay.enums.IdentityType;
import com.qd.p2p.sina.pay.param.CreateSingleHostingPayTradeParam;
import com.qd.p2p.sina.pay.response.CreateSingleHostingPayTradeResponse;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.common.constant.Summary;
import com.qdlc.p2p.common.constant.TradeCode;
import com.qdlc.p2p.common.constant.TradeStatus;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.core.redis.JedisCache;
import com.qdlc.p2p.common.core.redis.JedisCacheFactory;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.OrderNoUtil;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dto.TppTradeLog;

/**
 * 代付模版类
 * 代付通用逻辑处理类
 * <p/>
 *
 * @author wuaj
 */
public abstract class AbstractPayService implements CollectPayService {

    @Resource
    protected TppTradeService tppTradeService;

    @Resource
    protected SinaPayService sinaPayService;

    @Resource
    protected AccountDao accountDao;

    @Resource
    protected AccountService accountService;

    protected JedisCache<String> jedisCacheString = JedisCacheFactory.newInstance(String.class);

    @Override
    public boolean preCreateOrder() {
        return true;
    }

    @Override
    public void aftCreateOrder(TppTradeLog tppTradeLog) {
    }

    @Override
    public List<TppTradeLog> createOrders(Object... pars) {
        return null;
    }

    @Override
    public TppTradeLog createOrder(Object... pars) {
        analyzePars(pars);
        if (preCreateOrder()) {
            // 生成订单号
            String orderNo = OrderNoUtil.getInstance().getSerialNumber();
            // 可变参数
            TppTradeLog tppTradeLog = getTppTradeLog();
            // 固定参数
            tppTradeLog.setOrderNo(orderNo); // 新订单号
            tppTradeLog.setRemark(getBusinessName().concat("订单生成"));
            tppTradeLog.setTradeStatus(TradeStatus.TRADE_STATUS_WAIT_PAY.getStatus());
            tppTradeLog.setAddTime(DateUtil.getNow()); // 交易时间
            tppTradeLog.setAmount(0d);                 // 交易金额
            tppTradeLog.setSinaStatus("");
            tppTradeService.save(tppTradeLog);
            aftCreateOrder(tppTradeLog);
            return tppTradeLog;
        }
        return null;
    }

    @Override
    public ReturnResult requestOrder(TppTradeLog tppTradeLog) {
        // 新浪备注
        CreateSingleHostingPayTradeResponse response = null;
        try {
            Summary summary = Summary.getSummaryByType(tppTradeLog.getServiceType());
            // 调用代付接口
            CreateSingleHostingPayTradeParam param = new CreateSingleHostingPayTradeParam();
            param.setOutTradeNo(tppTradeLog.getOrderNo())
                    .setPayeeIdentityId(tppTradeLog.getToTppUserCustId())
                    .setPayeeIdentityType(IdentityType.UID) // 目前代付都是UID 给平台的都走分帐
                    .setAccountType(AccountType.SAVING_POT) // 目前代付都是存钱罐 给平台的都走分帐
                    .setOutTradeCode(TradeCode.C2001)
                    .setAmount(tppTradeLog.getMoney())
                    .setSummary(summary.getSummaryName() + tppTradeLog.getOrderNo())
                    .setSplitList(StringUtil.isNull(tppTradeLog.getSplitList()))
                    .setNotifyUrl(getCallBackUrl());
            if (!isSuspend(tppTradeLog.getTradeType())) {
                response = sinaPayService.createSingleHostingPayTrade(param);
            }
        } catch (Exception ex) {
            // do nothing
            ex.printStackTrace();
        }
        // 代付调用成功
        if (response != null && response.success()) {
            tppTradeLog.setRemark(getBusinessName().concat("提交成功"));
            tppTradeService.update(tppTradeLog);
            requestOrderSuccess(tppTradeLog); // 请求成功处理
        } else {
            String message = response == null ? "RPC调用失败" : MessageFormat.format("代付失败!reqStatus:{0} reqErrorMessage:{1} resCode:{2} resMessage:{3}",
                    response.getReqStatus(), response.getReqErrorMessage(), response.getResponseCode(),
                    response.getResponseMessage());
            String responseMessage = response == null ? "RPC调用失败" : response.getResponseMessage();
            logger.info(message);

            // 置为废单
            tppTradeLog.setTradeStatus(TradeStatus.TRADE_STATUS_INVALID.getStatus());
            tppTradeLog.setRemark(getBusinessName().concat("提交失败-" + responseMessage));
            tppTradeService.update(tppTradeLog);
            requestOrderFail(tppTradeLog); // 请求失败处理
            return new ReturnResult(true, message);
        }
        return ReturnResult.SUCCESS;
    }

    @Override
    public void requestOrderSuccess(TppTradeLog tppTradeLog) {
    }

    @Override
    public void requestOrderFail(TppTradeLog tppTradeLog) {
    }

    /**
     * 交易完成状态更新
     */
    protected void tradeFinishForStatus(TppTradeLog tppTradeLog, String depositStatus, double tradeAmount) {
        tppTradeLog.setAmount(tradeAmount); // 实际交易金额
        tppTradeLog.setTradeTime(DateUtil.getNow()); // 交易成功时间
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易完成"));
    }

    /**
     * 交易成功状态更新
     */
    protected void tradeSuccessForStatus(TppTradeLog tppTradeLog, String depositStatus) {
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易成功"));
    }

    /**
     * 交易失败状态更新
     */
    protected void tradeFailForStatus(TppTradeLog tppTradeLog, String depositStatus) {
        tppTradeLog.setTradeTime(DateUtil.getNow()); // 交易失败时间
        tppTradeService.updateTradeLog(tppTradeLog, depositStatus, getBusinessName().concat("交易失败"));
    }

    /**
     * 代收是否需要挂起
     */
    protected boolean isSuspend(String tradeType){
        if (StringUtil.isNotEmpty(tradeType)) {
            String suspend = jedisCacheString.get("SP_" + tradeType);
            return StringUtil.isNotEmpty(suspend) && suspend.equals("true");
        }
        return false;
    }
}